package com.project.service.impl;

import com.common.api.ApprovalApi;
import com.common.core.domain.AjaxResult;
import com.common.core.domain.entity.ProcessConfig;
import com.common.core.domain.entity.SysUser;
import com.common.core.service.ProcessConfigService;
import com.common.utils.CurrentRoleUtils;
import com.common.utils.SecurityUtils;
import com.common.utils.StringUtils;
import com.common.utils.bean.BizProcessMessages;
import com.common.utils.bean.ReflectionUtils;
import com.flowable.domain.vo.FlowQueryVo;
import com.flowable.domain.vo.task.BpmTaskApproveReqVO;
import com.flowable.service.IFlowTaskService;
import com.project.domain.entity.BizYfContract;
import com.project.domain.entity.xjProject.BizXjProject;
import com.project.domain.entity.zxProject.BizZxProject;
import com.project.mapper.YfContractMapper;
import com.project.mapper.xjProject.XjProjectMapper;
import com.project.mapper.zxProject.ZxProjectMapper;
import com.project.service.IYfContractService;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@Service
public class ProCheckCommon {
    //发起流程
    @Autowired
    private ApprovalApi approvalApi;

    //流程引擎
    @Autowired
    private IFlowTaskService flowTaskService;

    @Autowired
    private SqlSession sqlSession;

    @Autowired
    private ProjectInitServiceImpl projectInitService;

    @Autowired
    private XJProjectServiceImpl xjProjectService;

    @Autowired
    private IYfContractService yfContractService;

    /**
     * 更新主表审核字段
     * @param obj
     * @param clazz
     * @param proId
     * @param submitType
     * @param processType
     * @param checkStatus
     * @param proClass
     * @return
     * @param <T>
     */
    public <T> AjaxResult upDateZBCheckInfo(T obj, Class<T> clazz, String proId, Integer submitType, String processType,String checkStatus,String taskId,String proClass){
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey(); //当前角色
        if (obj == null || clazz == null ) {
            return AjaxResult.error("参数不能为空");
        }
        try{
            setField(obj, clazz, "id", proId);

            //给最后编辑人、编辑时间、编辑人id这些字段赋值
          /*  SysUser loginUser = SecurityUtils.getLoginUser().getUser();
            Date date = new Date();
            SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            setField(obj, clazz, "lastedituserid", loginUser.getUserRealId());
            setField(obj, clazz, "lasteditusername", loginUser.getNickName());
            setField(obj, clazz, "lasteditdate", dateFormat.parse(dateFormat.format(date)));*/

            if(submitType != null){
                switch (submitType){
                    case -1:{
                        //暂存：基础信息已保存,只处理状态;
                        if(!currentRoleKey.equals("biz_kyms") && !currentRoleKey.equals("biz_kycgly") || !StringUtils.isNotBlank(checkStatus) || checkStatus.equals("-2")){
                            setField(obj, clazz, "checkstatus", "-1");//科研管理员、秘书的暂存都不改状态
                            this.updatZB(obj);
                        }
                        return AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS,proId);
                    }
                    case 1:{
                        //提交（科研人员）：基础信息已保存,仅发起流程，更新主表审核状态（实例id流程模块处理）
                        obj = ReflectionUtils.updateFields(obj, clazz);
                        setField(obj, clazz, "checkstatus", "1");
                        int upRes = this.updatZB(obj);
                        if(upRes>0){
                            String processInstanceId = approvalApi.businessEntryApproval(proId, processType);//发起流程并返回示例id
                            return !StringUtils.isNotBlank(processInstanceId)?AjaxResult.warn(BizProcessMessages.OPERATE_FAIL):AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS,proId);
                        }else{
                            return AjaxResult.warn(BizProcessMessages.OPERATE_FAIL);
                        }
                    }
                    case 2:{
                        if(checkStatus.equals("1")){
                            //审核中的保存并通过：页签信息已保存，直接调审核接口
                            try{
                                BpmTaskApproveReqVO bta = new BpmTaskApproveReqVO();
                                bta.setId(taskId);
                                bta.setReason(SecurityUtils.getNickName() + "保存并通过");
                                flowTaskService.approveTask(SecurityUtils.getUserId(), bta);
                                return AjaxResult.success(BizProcessMessages.SAVE_SUCCESS,proId);
                            }catch (Exception exception){
                                return AjaxResult.warn(BizProcessMessages.SAVE_SUCCESS_APPROVE_FAIL);
                            }
                        }else{
                            //非审核中的保存并通过：页签信息已保存，审核改状态为2且流程实例id置为0,生成项目编号后更新主表
                            setField(obj, clazz, "checkstatus", "2");
                            setField(obj, clazz, "processInstanceId", "0");
                            obj = ReflectionUtils.updateFields(obj, clazz);
//                            setField(obj,clazz,"code",proCode);
                            //审核通过之后调各自的业务
                            if(this.updatZB(obj)>0){
                                if(proClass.equals("xJProject")){
                                    xjProjectService.updateBusinessStatus("biz_xj_project",proId,"2",null);
                                }else if(proClass.equals("zXProject")){
                                    projectInitService.updateBusinessStatus("biz_zx_project",proId,"2",null);
                                }else{
                                    yfContractService.updateBusinessStatus("biz_yf_contract",proId,"2",null);
                                }

                                return AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS,proId);
                            }else{
                                return AjaxResult.error(BizProcessMessages.OPERATE_FAIL);
                            }
                        }
                    }
                    default:return AjaxResult.error(BizProcessMessages.OPERATE_FAIL,proId);
                }
            }else {
                //没有submitType时默认都操作成功
                return AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS,proId);
            }
        }catch (NoSuchFieldException e) {
            return AjaxResult.error("类 " + clazz.getSimpleName() + " 缺少必要的字段: " + e.getMessage());
        } catch (IllegalAccessException e) {
            return AjaxResult.error("无法访问字段"+ e);
        }
    }

    // 通用字段赋值方法
    private static <T> void setField(T obj, Class<T> clazz, String fieldName, Object value)
            throws NoSuchFieldException, IllegalAccessException {
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public <T> int updatZB(T obj){
        try{
            XjProjectMapper xjProjectMapper = sqlSession.getMapper(XjProjectMapper.class);
            ZxProjectMapper zxProjectMapper = sqlSession.getMapper(ZxProjectMapper.class);
            YfContractMapper yfContractMapper = sqlSession.getMapper(YfContractMapper.class);

            if (obj instanceof BizXjProject) {
                BizXjProject xiObj = (BizXjProject) obj;
                return xjProjectMapper.updateById(xiObj);
            }

            if (obj instanceof BizZxProject) {
                BizZxProject zxObj = (BizZxProject) obj;
                return zxProjectMapper.updateById(zxObj);
            }

            if (obj instanceof BizYfContract) {
                BizYfContract yfObj = (BizYfContract) obj;
                return yfContractMapper.updateById(yfObj);
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
            return 0;
        }

         return 0;
    }
}
